package learn.net.udp;

import java.net.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;

public class UDPEchoClient {

  public  final static int DEFAULT_PORT = 7;
  private final static int LIMIT = 100;
 
  public static void main(String[] args) {

    int port = DEFAULT_PORT;
    try {
      port = Integer.parseInt(args[1]);
    }
    catch (Exception ex) {
    }
    
    SocketAddress remote;
    try {
      remote = new InetSocketAddress(args[0], port);
    }
    catch (Exception ex) {
      System.err.println("Usage: java UDPEchoClientWithChannels host [port]");
      return;   
    }
    
    try {
      DatagramChannel channel = DatagramChannel.open();
      channel.configureBlocking(false);
      channel.connect(remote);
      
      Selector selector = Selector.open();
      channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
      
      ByteBuffer buffer = ByteBuffer.allocate(4);
      int n = 0;
      int numbersRead = 0;
      while (true) {
        // wait one minute for a connection
        selector.select(60000);
        Set readyKeys = selector.selectedKeys();
        if (readyKeys.isEmpty() && n == LIMIT) { 
          // All packets have been written and it doesn't look like any 
          // more are will arrive from the network
          break;
        }
        else {
          Iterator iterator = readyKeys.iterator();
          while (iterator.hasNext()) {
            SelectionKey key = (SelectionKey) iterator.next();
            iterator.remove();
            if (key.isReadable()) {
              buffer.clear();
              channel.read(buffer);
              buffer.flip();
              int echo = buffer.getInt();
              System.out.println("Read: " + echo);
              numbersRead++;
            } 
            if (key.isWritable()) {
              buffer.clear();
              buffer.putInt(n);
              buffer.flip();
              channel.write(buffer);
              System.out.println("Wrote: " + n);
              n++;
             if (n == LIMIT) {
                // All packets have been written; switch to read-only mode
                key.interestOps(SelectionKey.OP_READ);
              } // end if
            }  // end while
          } // end else
        }  // end while

      }  // end while
      System.out.println("Echoed " + numbersRead + " out of " + LIMIT + " sent");
      System.out.println("Success rate: " + 100.0 * numbersRead / LIMIT + "%");
 
    }  // end try
    catch (IOException ex) {
      System.err.println(ex);
    }  // end catch

  }  // end main

}